#include "HelloWorldScene.h"
#include "CockExplodsion.h"
#include "cocos2d.h"
#include "PicResource.h"
#include "CommonConst.h"

using namespace cocos2d;

StartToken::~StartToken(){}
StartToken::StartToken(){

	CCSprite *backGround = CCSprite::create(b_Background);
	backGround->setPosition( ccp(backGround->getContentSize().width/2, backGround->getContentSize().height/2) );
	this->addChild(backGround);
	this->scheduleOnce( schedule_selector(StartToken::update), 3.0f); 
}

void StartToken::update(float dt)
{
	CCScene* bigCock = HelloWorld::scene();
	CCScene* newScene = CCTransitionCrossFade::create(1.5f, bigCock);
	bigCock->release();
	if (newScene)
	{
		CCDirector::sharedDirector()->replaceScene(newScene);
	} 
}

HelloWorld::~HelloWorld()
{	if (_targets) {		
		_targets->release();		
		_targets = NULL;	
	}	
	if (_projectiles) {		
		_projectiles->release();		
		_projectiles = NULL;	
	}	
}

HelloWorld::HelloWorld():_targets(NULL), _projectiles(NULL), _projectilesDestroyed(0), countScore(0){

}
CCScene* HelloWorld::scene()
{
    CCScene * scene = NULL;
    do 
    {
        // 'scene' is an autorelease object
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

        // 'layer' is an autorelease object
        HelloWorld *layer = HelloWorld::create();
        CC_BREAK_IF(! layer);

        // add layer as a child to scene
        scene->addChild(layer);
    } while (0);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    bool bRet = false;
	setTouchEnabled(true);

    do 
    {
        CC_BREAK_IF(!CCLayerColor::initWithColor( ccc4(255,255,255,255) ));

		CCSprite *backGround = CCSprite::create(b_Background);
		backGround->setPosition( ccp(backGround->getContentSize().width/2, backGround->getContentSize().height/2) );
		this->addChild(backGround);
        CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
            "exit.png",
            "exit.png",
            this,
            menu_selector(HelloWorld::menuCloseCallback));
        CC_BREAK_IF(! pCloseItem);
        pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 60, 60));


        CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
        pMenu->setPosition(CCPointZero);
        CC_BREAK_IF(! pMenu);
        this->addChild(pMenu, 1);

		pLabel = CCLabelTTF::create("0", "Arial", 60);
		pLabel->setColor(ccc3(255, 255, 255));
		CC_BREAK_IF(! pLabel);
        CCSize size = CCDirector::sharedDirector()->getWinSize();
        pLabel->setPosition(ccp(size.width / 2, size.height - 50));
        this->addChild(pLabel, 1);

		_targets = new CCArray;		
		_projectiles = new CCArray;

		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	    CCSprite *player = CCSprite::create("penguin.png", CCRectMake(0, 0, 360, 360) );
		player->setPosition( ccp(player->getContentSize().width/2, winSize.height/2) );
		this->addChild(player);
		this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0f );
		this->schedule( schedule_selector(HelloWorld::updateGame) );

		this->setTouchEnabled(true);
			
        bRet = true;
    } while (0);

    return bRet;
}

void HelloWorld::gameLogic(float dt)
{
	int randNum = rand() % MOST_ENEMY_NUM;
	int randType = 0;
	for (int i=1; i<= randNum; i++) {
		randType = rand() % ENEMY_TYPE_NUM;
		this->addTarget(randType);
	}
}

void HelloWorld::addTarget(int type)
{
	CCSprite *target = CCSprite::create(b_EnemyPics[type].data());
	
	// Determine where to spawn the target along the Y axis
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	int minY = target->getContentSize().height/2;
	int maxY = winSize.height - target->getContentSize().height/2;
	int rangeY = maxY - minY;

	// srand( TimGetTicks() );
    int actualY = ( rand() % rangeY ) + minY;
	// Create the target slightly off-screen along the right edge,

	// and along a random position along the Y axis as calculated
	target->setPosition(ccp(winSize.width, actualY));
	this->addChild(target);
	// Determine speed of the target
	int minDuration = (int)2.0;
	int maxDuration = (int)4.0;
	int rangeDuration = maxDuration - minDuration;
	// srand( TimGetTicks() );

	int actualDuration = ( rand() % rangeDuration ) + minDuration;
    // Create the actions
    CCFiniteTimeAction* actionMove = CCMoveTo::create( actualDuration,
                                               ccp(0, rand() % ((int)winSize.height)) );

    CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create( this,
				                                      callfuncN_selector(HelloWorld::spriteMoveFinished));

	target->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );
	target->setTag(type);
	_targets->addObject(target);
}

void HelloWorld::spriteMoveFinished(CCNode* sender)
{
	CCSprite *sprite = (CCSprite *)sender;
	this->removeChild(sprite, true);
	if (sprite->getTag() == ENEMY_YELLOW || sprite->getTag() == ENEMY_BLACK || sprite->getTag() == ENEMY_RED) {
		_targets->removeObject(sprite);
	}
	else if (sprite->getTag() == PROJECTTIE_TOKEN) {
		_projectiles->removeObject(sprite);
	}
}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    // "close" menu item clicked
    CCDirector::sharedDirector()->end();
}


void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
{

	// Choose one of the touches to work with

	CCTouch* touch = (CCTouch*)( touches->anyObject() );
	CCPoint location = touch->getLocation();    
	
	// Set up initial location of projectile

	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	CCSprite *projectile = CCSprite::create();
	projectile->setPosition( ccp(360, winSize.height/2 + 43) );

	CCParticleSun *projectileFire = CCParticleSun::create();
	projectileFire->retain();
	projectileFire->setTexture(CCTextureCache::sharedTextureCache()->addImage(b_ProjectileFire));
	projectileFire->setPosition( ccp(0, 0) );
	projectile->addChild(projectileFire, 0, 1);
	
	// Determinie offset of location to projectile

	int offX = location.x - projectile->getPosition().x;
	int offY = location.y - projectile->getPosition().y;

	// Bail out if we are shooting down or backwards
	if (offX <= 0) return;
	// Ok to add now - we've double checked position

	this->addChild(projectile);
	
	// Determine where we wish to shoot the projectile to

	int realX = winSize.width + (projectile->getContentSize().width/2);
	float ratio = (float)offY / (float)offX;
	int realY = (realX * ratio) + projectile->getPosition().y;
	CCPoint realDest = ccp(realX, realY);
	// Determine the length of how far we're shooting
	int offRealX = realX - projectile->getPosition().x;
	int offRealY = realY - projectile->getPosition().y;
	float length = sqrtf((offRealX * offRealX) + (offRealY*offRealY));
	float velocity = 480/1; // 480pixels/1sec
	float realMoveDuration = length/velocity;
	// Move projectile to actual endpoint

	projectile->runAction( CCSequence::create(
	CCMoveTo::create(realMoveDuration, realDest),
	CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL) );
	projectile->setTag(PROJECTTIE_TOKEN);
	_projectiles->addObject(projectile);
}



void HelloWorld::updateGame(float dt)
{
	CCArray *projectilesToDelete = new CCArray;
	CCObject* it = NULL;
	CCObject* jt = NULL;

	// for (it = _projectiles->begin(); it != _projectiles->end(); it++)
	CCARRAY_FOREACH(_projectiles, it)
	{
		CCSprite *projectile = dynamic_cast<CCSprite*>(it);
		CCRect projectileRect = CCRectMake(
			projectile->getPosition().x - (projectile->getContentSize().width/2),
			projectile->getPosition().y - (projectile->getContentSize().height/2),
			projectile->getContentSize().width,
			projectile->getContentSize().height);

		CCArray* targetsToDelete =new CCArray;

		// for (jt = _targets->begin(); jt != _targets->end(); jt++)
		CCARRAY_FOREACH(_targets, jt)
		{
			CCSprite *target = dynamic_cast<CCSprite*>(jt);
			CCRect targetRect = CCRectMake(
				target->getPosition().x - (target->getContentSize().width/2),
				target->getPosition().y - (target->getContentSize().height/2),
				target->getContentSize().width,
				target->getContentSize().height);

			// if (CCRect::CCRectIntersectsRect(projectileRect, targetRect))
			if (projectileRect.intersectsRect(targetRect))
			{
				CockExplodsion *explodsion = CockExplodsion::create();
				this->addChild(explodsion, 10);
				explodsion->setTexture(CCTextureCache::sharedTextureCache()->addImage(b_Explode) );
				explodsion->setAutoRemoveOnFinish(true);
				explodsion->setPosition( ccp(target->getPosition().x, target->getPosition().y ) );

				targetsToDelete->addObject(target);
				countScore +=  target->getTag()+1;
				char score[10] = {0};
				sprintf(score, "%d", countScore);
				pLabel->setString(score);
			}
		}

		// for (jt = targetsToDelete->begin(); jt != targetsToDelete->end(); jt++)
		CCARRAY_FOREACH(targetsToDelete, jt)
		{
			CCSprite *target = dynamic_cast<CCSprite*>(jt);
			_targets->removeObject(target);
			this->removeChild(target, true);

			_projectilesDestroyed++;
			/*if (_projectilesDestroyed >= 5)
			{
				GameOverScene *gameOverScene = GameOverScene::create();
				gameOverScene->getLayer()->getLabel()->setString("You Win!");
				CCDirector::sharedDirector()->replaceScene(gameOverScene);
			}*/
		}

		if (targetsToDelete->count() > 0)
		{
			projectilesToDelete->addObject(projectile);
		}
		targetsToDelete->release();
	}

	// for (it = projectilesToDelete->begin(); it != projectilesToDelete->end(); it++)
	CCARRAY_FOREACH(projectilesToDelete, it)
	{
		CCSprite* projectile = dynamic_cast<CCSprite*>(it);
		_projectiles->removeObject(projectile);
		this->removeChild(projectile, true);
	}
	projectilesToDelete->release();
}
